
#include <cassert>
#include <iostream>
#include <string>
using namespace std;

#include <windows.h>
#include "Grammer2.h"

//=================================================
void PrintRange(const void * begin, const void * end)
{
	for (char * c = (char *)begin; c < end; c++)
	{
		cout<<*c;
	}
}
//=================================================

//enum InstructionCode
//{
//	EXPR, INTEGER, FLOATING
//};
//
//template<unsigned int C> struct Instruction;
//
//template<>
//struct Instruction<INTEGER>
//{
//	int value;
//	static inline void write(Instruction<INTEGER> & I, const char * begin, const char * end)
//	{
//		I.value = atoi(begin);
//	}
//};
//
//struct InstructionItem
//{
//	InstructionCode code;
//};
//
//
//CodeItem(Operation, argbuf, size);
//pushr(CodeItem);
//pushl(CodeItem);
//
//
//class PhraseNode
//{
//public:
//	PhraseNode(Operation);
//public:
//	void reduce(PhraseNode * pn)
//	{
//
//	}
//private:
//	const char * m_base;
//	unsigned int m_size;
//};
//
//
//class ParserContext
//{
//public:
//	store(const Operation &);
//
//};

//template<typename T>
//struct PriorityOfElement;
//
//class IInstruction
//{a
//public:
//	
//
//};
//
//
//
//
//template<typename T>
//class Dataunit
//{
//public:
//	Instruction(
//};
//PushData
//PopData
//PushCode
//PopCode
//
//while (sp > sb)
//{
//	Codeunit * unit = sp;
//	unit->flake();
//}
//
//class myAddCodeunit:public Codeunit
//{
//public:
//	virtual void flake(IDataunit * du)
//	{
//		
//
//	}
//};
//



//=================================================




BEGIN_REDUCER(Expr)
	PrintRange(begin, end);
	cout<<":Expr"<<endl;
	//context->commit(1, begin, *end);
	return true;
END_REDUCER

BEGIN_REDUCER(Token_IntegerNumber)
	PrintRange(begin, end);
	cout<<":integer"<<endl;
//	*((int*)newbase) = atoi(begin);
//	context->archive(sizeof(int));
//	context->PushData(Dataunit<Element_IntegerNumver>(1000));
//	context->commit(2, begin, *end);
	return true;
END_REDUCER


BEGIN_REDUCER(Token_FloatingNumber)
	PrintRange(begin, end);
	cout<<":floating"<<endl;	
//	*((double*)newbase) = atof(begin);
//	context->archive(sizeof(double));
//		context->commit(3, begin, *end);
	return true;
END_REDUCER


BEGIN_REDUCER(Element_Operator)
	PrintRange(begin, end);
	cout<<":operator"<<endl;
	return true;
END_REDUCER


BEGIN_REDUCER(Term)
	PrintRange(begin, end);
	cout<<":Term"<<endl;
	return true;
END_REDUCER


BEGIN_REDUCER(Factor)
	PrintRange(begin, end);
	cout<<":Factor"<<endl;
	return true;
END_REDUCER

//BEGIN_REDUCER(Token_String)
//	PrintRange(begin, end);
//	cout<<":String"<<endl;
//	return true;
//END_REDUCER


BEGIN_REDUCER(MulOp)
	PrintRange(begin, end);
	cout<<":op(mul)"<<endl;
	return true;
END_REDUCER

BEGIN_REDUCER(AddOp)
	PrintRange(begin, end);
	cout<<":op(add)"<<endl;
	return true;
END_REDUCER

BEGIN_REDUCER(NullToken)
	PrintRange(begin, end);
	cout<<":null"<<endl;
	return true;
END_REDUCER



BEGIN_REDUCER(Element_DecNumber)
	PrintRange(begin, end);
	cout<<":digit"<<endl;
	return true;
END_REDUCER


class TestContext:public ParserContext
{
public:
	TestContext():stacktop(stackbuf) {;}
	virtual ~TestContext() {;}
public:
	void * prepare()
	{
		return stacktop;
	}

	bool rollback(void * session)
	{
		this->stacktop = (int*)session;
		return true;
	}

	bool submit(void * data, unsigned int len)
	{
		memcpy(stacktop, data, len);
		return true;
	}
private:
	int		stackbuf[4096];
	int *	stacktop;
};


int main()
{

	TestContext context;

	/*
	//parser< SExpr >::dump();
	makeparser<ParserContext>::parse(iterator begin, ):
	*/

	char buffer[4096] = {0};
	for(;;)
	{
		cin.getline(buffer, 4096);

		unsigned long duration = GetTickCount();

		char * finish = 0;

		if (!parser<Expr>::parse(context, buffer, &finish))
		{
			cout<<"Error at offset "<<finish - buffer<<":"<<finish<<endl;
		}

	
		duration = GetTickCount() - duration;

		cout<<"Used time: "<<duration<<" ms. "<<(finish - buffer)<<" words processed."<<endl;
		if (*finish == '\0')
		{
			cout<<"EOF."<<endl;
		}
		else
		{
			cout<<"interrupt."<<endl;
		}
	}

	return 0;
}



/*

#include <string>
#include <algorithm>
struct AuthCollect:public ICollectable
{

	template<typename code>
	struct notation
	{
		template<typename _ForwardIterator, typename _OutputIterator> 
		static bool match(_ForwardIterator first, _OutputIterator next)
		{
			//return code == (*first) ? (*next = first++, true) : false;
			//return code == (first, ) ? (*next = first++, true) : false;
		}
	}

	template<typename _Pred>
	struct notation
	{
		template<typename _ForwardIterator, typename _OutputIterator> 
		static bool match(_ForwardIterator first, _OutputIterator next)
		{
			return _Pred(first, next);
		}
	}

	bool _CHARINSTR_(char * first, char ** next)
	{
		if ((*first) != TC('"') && (*first) >= 32 && (*first) < 127)
		{
			if (TC('\\') == *first && char('"') == *(first + 1))
			{
				*next = first + sizeof(char) + sizeof(char);
			}
			else
			{
				*next = first + sizeof(char);
			}
			return true;
		}
		return false;
	}


	template <char code>
	struct eator
	{
		template<typename _ForwardIterator, typename _OutputIterator>
		bool operator(_ForwardIterator first, _OutputIterator next)
		{
			return code == (*first) ? (*next = first++, true) : false;
		}
	};

	typedef notation<_CHARINSTR_> Strchar;
	typedef notation< eator<'a'> > _a_;

	
	typedef token<_S_, _E_, _L_, _F_> token_self;

	typedef token<eator<'S'>, eator<'E'>, eator<'L'>, eator<'F'> > token_self;
	typedef token<'S', 'E', 'L', 'F'> token_self;


	template <char code>
	struct notation
	{
		template<typename _ForwardIterator, typename _OutputIterator>
		bool operator(_ForwardIterator first, _OutputIterator next)
		{
			return code == (*first) ? (*next = first++, true) : false;
		}
	}

	template <wchar_t code>
	struct notation
	{
		template<typename _ForwardIterator, typename _OutputIterator>
		bool operator(_ForwardIterator first, _OutputIterator next)
		{
			return code == (*first) ? (*next = first++, true) : false;
		}
	}

	template <typename _Pred>
	struct notation
	{
		template<typename _ForwardIterator, typename _OutputIterator>
		bool operator(_ForwardIterator first, _OutputIterator next)
		{
			return _Pred(first, next);
		}
	}



	template <typename  N1, typename N2 = void, typename N3 = void, typename N4 = void,
		typename N5 = void, typename N6 = void, typename N7 = void, typename N8 = void,
		typename N9 = void, typename N10= void, typename N11= void, typename N12= void,
		typename N13= void, typename N14= void, typename N15= void, typename N16= void,
		typename N17= void, typename N18= void, typename N19= void, typename N20= void,
		typename N21= void, typename N22= void, typename N23= void, typename N24= void,
		typename N25= void, typename N26= void, typename N27= void, typename N28= void,
		typename N29= void, typename N30= void, typename N31= void, typename N32= void>
	struct token
	{
		template<typename _Context, typename _ForwardIterator, typename _OutputIterator>
		static bool shift(_Context context, _ForwardIterator first, _OutputIterator next)
		{
			return notation<N1>(first, next)
					&& token<
						N2 , N3 , N4 , N5 , N6 , N7 , N8 , N9 ,
						N10, N11, N12, N13, N14, N15, N16, N17,
						N18, N19, N20, N21, N22, N23, N24, N25,
						N26, N27, M28, N29, N30, N31, N32, void
					>::shift(context, *next, next);
		}
	}



	template<typename _Lexical>
	struct reducer
	{
		template <typename _Context, typename _InputIterator>
		static bool reduce(_Context context, _InputIterator begin, _InputIterator end)
		{
			return true;
		}
	}


	template<typename _Lexical, typename _Context, typename _InputIterator> 
	bool dispose(_Context context, _InputIterator first, _InputIterator last)
	{
		void * session = context.prepare();
		if (!reducer<_Lexical>::reduce(context, first, last))
		{
			context.rollback(session);
			return false;
		}
		return true;
	}

	template <typename _Lexical>
	struct parser
	{
		template <typename _Context, typename _InputIterator, typename _OutputIterator>
		static bool parse(_Context context, _InputIterator first, _OutputIterator result)
		{
			return _Lexical::shift(context, first, result) && dispose<_Lexical>(context, first, *result);
		}
	};




	FieldNumber uid;
	FieldText	name;
public:
	void Collect(Storage&)
	{
		Storage<<uid<<name;
	}
};

struct UserCollect:public ICollectable
{
	FieldNumber mynumber;
	FieldText	mytext;
	FieldDate	mydate;
public:
	void Collect(Storage&)
	{
		Storage<<mynumber<<myname<<mydate<<myauth;
	}
};

UserCollect uc;
uc.mynumber = 122;
uc.mytext = "alskdal";
uc.mydate = "2009/03/02";
Storage<<uc;
UserCollect uc;
uc.mynumber.filter = NULL;
uc.mytext.filter = NULL;
uc.mydate.filter = Great("1970");
QueryResult<UserCollect>(uc) result;
Query>>result;



FieldNumber id;
FieldText  name;
FieldDate  date;

auth[field<name>("john")]
auth["john"].passwd = "passwd";
auth["john"].banned = false;
auth["john"].userid = 0;

auth[userid]

authdb = SelectDB("auth");
uid = authdb["john"].userid;
name = authdb[uid].name;
*/